/******************************************************************/
/*                                                                */
/*  Winpooch : Windows Watchdog                                   */
/*  Copyright (C) 2004-2007  Benoit Blanchon                      */
/*                                                                */
/*  This program is free software; you can redistribute it        */
/*  and/or modify it under the terms of the GNU General Public    */
/*  License as published by the Free Software Foundation; either  */
/*  version 2 of the License, or (at your option) any later       */
/*  version.                                                      */
/*                                                                */
/*  This program is distributed in the hope that it will be       */
/*  useful, but WITHOUT ANY WARRANTY; without even the implied    */
/*  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR       */
/*  PURPOSE.  See the GNU General Public License for more         */
/*  details.                                                      */
/*                                                                */
/*  You should have received a copy of the GNU General Public     */
/*  License along with this program; if not, write to the Free    */
/*  Software Foundation, Inc.,                                    */
/*  675 Mass Ave, Cambridge, MA 02139, USA.                       */
/*                                                                */
/******************************************************************/

#include <windows.h>
#include <wininet.h>
#include <imagehlp.h>
#include <shlwapi.h>
#include <stdio.h>
#include <conio.h>
#include <tchar.h>
#include <direct.h>
#include <setupapi.h>

#include "SymbolFile.h"

#define arraysize(A) (sizeof(A)/sizeof((A)[0]))


TCHAR szOutputFile[MAX_PATH] ;

LPCTSTR	szPrefix = TEXT("c:\\websymbols\\") ;


LPCTSTR aFunctionNames[] =
  {
    TEXT("ExfAcquirePushLockExclusive"),
    TEXT("ExfReleasePushLock"),
    TEXT("NtCreateProcess"),
    TEXT("NtCreateProcessEx"),
    TEXT("NtCreateSection"),
    TEXT("NtCreateUserProcess"),
    TEXT("NtTerminateProcess"),
    TEXT("NtQueryInformationFile"),
    TEXT("NtQueryKey"),
    TEXT("NtQueryValueKey"),
    TEXT("NtSetInformationFile"),
    TEXT("NtSetValueKey"),
    TEXT("ObQueryNameString"),
    TEXT("ObpFreeObject"),
    TEXT("PspTerminateProcess"),
    TEXT("swprintf"),
    //TEXT("ObFastDereferenceObject"),
    //TEXT("ObfDereferenceObject"),
    TEXT("ZwOpenProcess"),
    TEXT("ZwProtectVirtualMemory"),
    TEXT("ZwReadVirtualMemory")
  } ;

#define FUNCTION_COUNT arraysize(aFunctionNames)


typedef struct {
  LPCTSTR	szName ;
  LPCTSTR	szSymFilename ;
  LPCTSTR	szSymSignature ;
  BOOL		bDisabled ;
  LPVOID	aFunctions[FUNCTION_COUNT] ;
} VERSION_ENTRY;


VERSION_ENTRY aVersions[] =
{
  //
  // 5.00.2195.1
  //
  {
    TEXT("ntkrnlpa 5.00.2195.1 (english)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("384D5A86189840")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.1 (french)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("384D5A8618A6C0")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.1 (german)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("384D5A8618A200")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.1 (polish)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("384D5A86189E80")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.1 (english)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("384D9B17190900")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.1 (french)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("384D9B17191780")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.1 (german)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("384D9B171912C0")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.1 (polish)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("384D9B17190F40")
  }, 

  //
  // 5.00.2195.2951
  //
  {
    TEXT("ntkrnlpa 5.00.2195.2951 (french)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("3AD7789119C400")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.2951 (french)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("3AD7AD601A3280")
  }, 

  //
  // 5.00.2195.5438
  //
  {
    TEXT("ntkrnlpa 5.00.2195.5438 (german)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("3D362A9019C800")
  },
  {
    TEXT("ntkrnlpa 5.00.2195.5438 (polish)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("3D362A9019C580")
  },
  {
    TEXT("ntkrnlpa 5.00.2195.5438 (russian)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("3D362A9019BF40")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.5438 (german)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("3D366B8B1A2A00")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.5438 (polish)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("3D366B8B1A2780")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.5438 (russian)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("3D366B8B1A2140")
  }, 

  //
  // 5.00.2195.6717
  //  
/*
  {
    TEXT("ntkrpamp 5.00.2195.6717 (dutch)"),
    TEXT("ntkrpamp.dbg"),
    TEXT("3EE650CD1A3700")
  },
*/
  {
    TEXT("ntkrpamp 5.00.2195.6717 (english)"),
    TEXT("ntkrpamp.dbg"),
    TEXT("3EE650CD1A2B40")
  },
  {
    TEXT("ntkrpamp 5.00.2195.6717 (french)"),
    TEXT("ntkrpamp.dbg"),
    TEXT("3EE650CD1A3900")
  },
  {
    TEXT("ntkrpamp 5.00.2195.6717 (italian)"),
    TEXT("ntkrpamp.dbg"),
    TEXT("3EE650CD1C82C0")
  },
  {
    TEXT("ntkrnlpa 5.00.2195.6717"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("3EE650C919E740")
  },
  {
    TEXT("ntkrnlpa 5.00.2195.6717 (english)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("3EE650C919D980")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.6717 (german)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("3EE650C919E240")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.6717 (portuguese)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("3EE650C919E640")
  }, 
/*
  {
    TEXT("ntkrnlpa 5.00.2195.6717 (spanish)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("3EE650C919EDC0")
  },  
*/
  {
    TEXT("ntoskrnl 5.00.2195.6717"),
    TEXT("ntoskrnl.dbg"),
    TEXT("3EE6C0021A47C0")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.6717 (english)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("3EE6C0021A3A00")
  },
  {
    TEXT("ntoskrnl 5.00.2195.6717 (german)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("3EE6C0021A42C0")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.6717 (portuguese)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("3EE6C0021A46C0")
  }, 
/*
  {
    TEXT("ntoskrnl 5.00.2195.6717 (spanish)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("3EE6C0021A4E40")
  }, 
*/
/*
  {
    TEXT("ntkrnlmp 5.00.2195.6717 (dutch)"),
    TEXT("ntkrnlmp.dbg"),
    TEXT("3EE650B319E8C0")
  },
*/
  {
    TEXT("ntkrnlmp 5.00.2195.6717 (english)"),
    TEXT("ntkrnlmp.dbg"),
    TEXT("3EE650B319DD00")
  },
  {
    TEXT("ntkrnlmp 5.00.2195.6717 (french)"),
    TEXT("ntkrnlmp.dbg"),
    TEXT("3EE650B319EAC0")
  },
  {
    TEXT("ntkrnlmp 5.00.2195.6717 (italian)"),
    TEXT("ntkrnlmp.dbg"),
    TEXT("3EE650B31C3480")
  },

  //
  // 5.00.2195.6902
  //
  {
    TEXT("ntkrpamp 5.00.2195.6902 (german)"),
    TEXT("ntkrpamp.dbg"),
    TEXT("403D35F91A47C0")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.6902 (english)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("403D35F819EDC0")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.6902 (german)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("403D35F819F680")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.6902 (?)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("4047DB831A59C0")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.6902 (english)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("4047DB831A5540")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.6902 (german)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("4047DB831A5E00")
  }, 
  {
    TEXT("ntkrnlmp 5.00.2195.6902 (german)"),
    TEXT("ntkrnlmp.dbg"),
    TEXT("403D35E219F900")
  }, 

  //
  // 5.00.2195.6952
  //
  {
    TEXT("ntkrnlpa 5.00.2195.6952 (english)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("40D1D1AD19FF40")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.6952 (italian)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("40D1D1AD1C56C0")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.6952 (english)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("40D1D18319A640")
  },
  {
    TEXT("ntoskrnl 5.00.2195.6952 (italian)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("40D1D1831BFDC0")
  }, 

  //
  // 5.00.2195.6992
  //
  {
    TEXT("ntkrnlpa 5.00.2195.6992 (english)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("4177334C1A0180")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.6992 (italian)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("4177334C1C5900")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.6992 (spanish)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("4177334C1A15C0")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.6992 (english)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("4177333519A800")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.6992 (italian)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("417733351BFF80")
  },
  {
    TEXT("ntoskrnl 5.00.2195.6992 (spanish)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("4177333519BC40")
  },

  //
  // 5.00.2195.7035
  //
  {
    TEXT("ntkrnlpa 5.00.2195.7035 (english)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("42258C0E1A2480")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7035 (french)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("42258C0E1A3240")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7035 (german)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("42258C0E1A2D40")
  },
  {
    TEXT("ntkrnlpa 5.00.2195.7035 (spanish)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("42258C0E1A38C0")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.7035 (english)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("42258BD819CB80")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.7035 (french)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("42258BD819D940")
  },
  {
    TEXT("ntoskrnl 5.00.2195.7035 (german)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("42258BD819D440")
  },
  {
    TEXT("ntoskrnl 5.00.2195.7035 (spanish)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("42258BD819DFC0")
  }, 

  //
  // 5.00.2195.7045
  //
  {
    TEXT("ntkrpamp 5.00.2195.7045 (?)"),
    TEXT("ntkrpamp.dbg"),
    TEXT("427B58D31A7B40")
  }, 
  {
    TEXT("ntkrpamp 5.00.2195.7045 (french)"),
    TEXT("ntkrpamp.dbg"),
    TEXT("427B58D31A8900")
  }, 
  {
    TEXT("ntkrpamp 5.00.2195.7045 (german)"),
    TEXT("ntkrpamp.dbg"),
    TEXT("427B58D31A8400")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7045 (english)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("427B58D31A2480")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7045 (french)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("427B58D31A3240")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7045 (spanish)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("427B58D31A38C0")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7045 (1)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("427B58D31A2D40")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7045 (2)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("427B58D31C7C00")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.7045 (english)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("427B58BB19CB40")
  },
  {
    TEXT("ntoskrnl 5.00.2195.7045 (french)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("427B58BB19D900")
  },
  {
    TEXT("ntoskrnl 5.00.2195.7045 (spanish)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("427B58BB19DF80")
  },
  {
    TEXT("ntoskrnl 5.00.2195.7045 (1)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("427B58BB19D400")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.7045 (2)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("427B58BB1C22C0")
  }, 
  {
    TEXT("ntkrnlmp 5.00.2195.7045 (?)"),
    TEXT("ntkrnlmp.dbg"),
    TEXT("427B58BB1A2840")
  }, 
  {
    TEXT("ntkrnlmp 5.00.2195.7045 (french)"),
    TEXT("ntkrnlmp.dbg"),
    TEXT("427B58BB1A3600")
  }, 
  {
    TEXT("ntkrnlmp 5.00.2195.7045 (german)"),
    TEXT("ntkrnlmp.dbg"),
    TEXT("427B58BB1A3100")
  }, 

  //
  // 5.00.2195.7071
  //
  {
    TEXT("ntkrpamp 5.00.2195.7071 (english)"),
    TEXT("ntkrpamp.dbg"),
    TEXT("4344EC6C1A7D00")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7071 (english)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("4344EC6C1A25C0")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7071 (french)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("4344EC6C1A3380")
  },
  {
    TEXT("ntkrnlpa 5.00.2195.7071 (german)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("4344EC6C1A2E80")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7071 (italian)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("4344EC6C1C7D40")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7071 (spanish)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("4344EC6C1A3A00")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.7071 (english)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("4344EC5919CD80")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.7071 (french)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("4344EC5919DB40")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.7071 (german)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("4344EC5919D640")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.7071 (italian)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("4344EC591C2500")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.7071 (spanish)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("4344EC5919E1C0")
  }, 
  {
    TEXT("ntkrnlmp 5.00.2195.7071 (english)"),
    TEXT("ntkrnlmp.dbg"),
    TEXT("4344EC591A29C0")
  }, 

  //
  // 5.00.2195.7098
  //
  {
    TEXT("ntkrpamp 5.00.2195.7098 (english)"),
    TEXT("ntkrpamp.dbg"),
    TEXT("4492581F1A7C80")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7098 (english)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("4492581F1A2580")
  },
  {
    TEXT("ntkrnlpa 5.00.2195.7098 (french)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("4492581F1A3340")
  },
  {
    TEXT("ntkrnlpa 5.00.2195.7098 (italian)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("4492581F1C7D00")
  },   
  {
    TEXT("ntkrnlpa 5.00.2195.7098 (spanish)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("4492581F1A39C0")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.7098 (english)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("4492580919CD00")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.7098 (french)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("4492580919DAC0")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.7098 (italian)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("449258091C2480")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.7098 (spanish)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("4492580919E140")
  }, 
  {
    TEXT("ntkrnlmp 5.00.2195.7098 (english)"),
    TEXT("ntkrnlmp.dbg"),
    TEXT("449258091A2940")
  }, 

  //
  // 5.00.2195.7111
  //
  {
    TEXT("ntkrpamp 5.00.2195.7111 (english)"),
    TEXT("ntkrpamp.dbg"),
    TEXT("45069E891A7C80")
  }, 
  {
    TEXT("ntkrpamp 5.00.2195.7111 (french)"),
    TEXT("ntkrpamp.dbg"),
    TEXT("45069E891A8A40")
  }, 
  {
    TEXT("ntkrpamp 5.00.2195.7111 (italian)"),
    TEXT("ntkrpamp.dbg"),
    TEXT("45069E891CD400")
  }, 
  {
    TEXT("ntkrpamp 5.00.2195.7111 (polish)"),
    TEXT("ntkrpamp.dbg"),
    TEXT("45069E891A82C0")
  }, 
  {
    TEXT("ntkrpamp 5.00.2195.7111 (spanish)"),
    TEXT("ntkrpamp.dbg"),
    TEXT("45069E891A90C0")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7111"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("45069E861C7D00")
  },
  {
    TEXT("ntkrnlpa 5.00.2195.7111 (dutch)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("45069E861A3140")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7111 (english)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("45069E861A2580")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7111 (finnish)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("45069E861A27C0")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7111 (french)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("45069E861A3340")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7111 (german)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("45069E861A2E40")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7111 (greek)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("45069E861C8A80")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7111 (polish)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("45069E861A2BC0")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7111 (spanish)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("45069E861A39C0")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7111 (swedish)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("45069E861A7340")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.7111"),
    TEXT("ntoskrnl.dbg"),
    TEXT("45069E6E1C2480")
  },
  {
    TEXT("ntoskrnl 5.00.2195.7111 (dutch)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("45069E6E19D8C0")
  },
  {
    TEXT("ntoskrnl 5.00.2195.7111 (english)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("45069E6E19CD00")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.7111 (finnish)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("45069E6E19CF40")
  },
  {
    TEXT("ntoskrnl 5.00.2195.7111 (french)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("45069E6E19DAC0")
  },
  {
    TEXT("ntoskrnl 5.00.2195.7111 (german)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("45069E6E19D5C0")
  },
  {
    TEXT("ntoskrnl 5.00.2195.7111 (greek)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("45069E6E1C3200")
  },
  {
    TEXT("ntoskrnl 5.00.2195.7111 (polish)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("45069E6E19D340")
  },
  {
    TEXT("ntoskrnl 5.00.2195.7111 (spanish)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("45069E6E19E140")
  },
  {
    TEXT("ntoskrnl 5.00.2195.7111 (swedish)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("45069E6E1A1AC0")
  },
  {
    TEXT("ntkrnlmp 5.00.2195.7111 (english)"),
    TEXT("ntkrnlmp.dbg"),
    TEXT("45069E6E1A2900")
  },
  {
    TEXT("ntkrnlmp 5.00.2195.7111 (french)"),
    TEXT("ntkrnlmp.dbg"),
    TEXT("45069E6E1A36C0")
  },
  {
    TEXT("ntkrnlmp 5.00.2195.7111 (italian)"),
    TEXT("ntkrnlmp.dbg"),
    TEXT("45069E6E1C8080")
  },
  {
    TEXT("ntkrnlmp 5.00.2195.7111 (polish)"),
    TEXT("ntkrnlmp.dbg"),
    TEXT("45069E6E1A2F40")
  },
  {
    TEXT("ntkrnlmp 5.00.2195.7111 (spanish)"),
    TEXT("ntkrnlmp.dbg"),
    TEXT("45069E6E1A3D40")
  },

  //
  // 5.00.2195.7133
  //
  {
    TEXT("ntkrpamp 5.00.2195.7133 (english)"),
    TEXT("ntkrpamp.dbg"),
    TEXT("45EC3C9D1A7C80")
  }, 
  {
    TEXT("ntkrpamp 5.00.2195.7133 (french)"),
    TEXT("ntkrpamp.dbg"),
    TEXT("45EC3C9D1A8A40")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7133 (english)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("45EC3C9D1A2580")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7133 (french)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("45EC3C9D1A3340")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7133 (german)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("45EC3C9D1A2E40")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7133 (italian)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("45EC3C9D1C7D00")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7133 (polish)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("45EC3C9D1A2BC0")
  }, 
  {
    TEXT("ntkrnlpa 5.00.2195.7133 (spanish)"),
    TEXT("ntkrnlpa.dbg"),
    TEXT("45EC3C9D1A39C0")
  }, 
  {
    TEXT("ntoskrnl 5.00.2195.7133 (english)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("45EC3C8F19CD00")
  },
  {
    TEXT("ntoskrnl 5.00.2195.7133 (french)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("45EC3C8F19DAC0")
  },
  {
    TEXT("ntoskrnl 5.00.2195.7133 (german)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("45EC3C8F19D5C0")
  },
  {
    TEXT("ntoskrnl 5.00.2195.7133 (italian)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("45EC3C8F1C2480")
  },
  {
    TEXT("ntoskrnl 5.00.2195.7133 (polish)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("45EC3C8F19D340")
  },
  {
    TEXT("ntoskrnl 5.00.2195.7133 (spanish)"),
    TEXT("ntoskrnl.dbg"),
    TEXT("45EC3C8F19E140")
  },
  {
    TEXT("ntkrnlmp 5.00.2195.7133 (english)"),
    TEXT("ntkrnlmp.dbg"),
    TEXT("45EC3C8F1A2940")
  },
  {
    TEXT("ntkrnlmp 5.00.2195.7133 (french)"),
    TEXT("ntkrnlmp.dbg"),
    TEXT("45EC3C8F1A3700")
  },

  //
  // 5.1.2600.0
  //  
  {
    TEXT("ntkrnlpa 5.1.2600.0 (xpclient.010817-1148)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("0ABB7E73C24942C6A610FDB19159E3CC1")
  }, 
  {
    TEXT("ntoskrnl 5.1.2600.0 (xpclient.010817-1148)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("DA37FCA19A614EB98EE2A3CF30E625392")
  }, 

  //
  // 5.1.2600.31
  //  
  {
    TEXT("ntkrnlpa 5.1.2600.31 (xpclnt_qfe.010827-1803)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("80423993DFF1461BB91D5B2FF59D15604")
  }, 
  {
    TEXT("ntoskrnl 5.1.2600.31 (xpclnt_qfe.010827-1803)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("A6C32BE0B0FD4CE7B42CF7C11D3214FC4")
  },

  //
  // 5.1.2600.34
  //  
  {
    TEXT("ntkrnlpa 5.1.2600.34 (xpclnt_qfe.010827-1803)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("80423993DFF1461BB91D5B2FF59D15607")
  }, 
  {
    TEXT("ntoskrnl 5.1.2600.34 (xpclnt_qfe.010827-1803)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("A6C32BE0B0FD4CE7B42CF7C11D3214FC7")
  }, 

  //
  // 5.1.2600.108
  //  
  {
    TEXT("ntkrnlpa 5.1.2600.108 (xpclnt_qfe.021108-2107)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("E086B943FAE142BEBD7E5F280ADF14585")
  }, 
  {
    TEXT("ntoskrnl 5.1.2600.108 (xpclnt_qfe.021108-2107)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("15317AB7420A427FB0CD6DEFE09530A35")
  }, 

  //
  // 5.1.2600.115
  //  
  {
    TEXT("ntkrnlpa 5.1.2600.115 (xpclnt_qfe.021108-2107)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("E086B943FAE142BEBD7E5F280ADF14587")
  }, 
  {
    TEXT("ntoskrnl 5.1.2600.115 (xpclnt_qfe.021108-2107)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("15317AB7420A427FB0CD6DEFE09530A37")
  }, 

  //
  // 5.1.2600.160
  //  
  {
    TEXT("ntkrnlpa 5.1.2600.160 (xpclnt_qfe.021108-2107)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("A75D8A76665C4D4DA4286E245C3320974")
  }, 
  {
    TEXT("ntoskrnl 5.1.2600.160 (xpclnt_qfe.021108-2107)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("BC5D15F5C30D4E8C849E0857971617334")
  }, 

  //
  // 5.1.2600.170
  //  
  {
    TEXT("ntkrnlpa 5.1.2600.170 (xpclnt_qfe.040918-1927)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("046187ECF3F24BE489524C95C7994FEA1")
  }, 
  {
    TEXT("ntoskrnl 5.1.2600.170 (xpclnt_qfe.040918-1927)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("912DA83FA66542CFAB146073FAFBB8621")
  }, 

  //
  // 5.1.2600.1106
  //
  {
    TEXT("ntkrpamp 5.1.2600.1106 (xpsp1.020828-1920)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("656C04779CB54983AD8A6B57C363469C1")
  },
  {
    TEXT("ntkrnlpa 5.1.2600.1106 (xpsp1.020828-1920)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("EBC8148525684CCEBF8D3491B68F67211")
  },
  {
    TEXT("ntoskrnl 5.1.2600.1106 (xpsp1.020828-1920)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("C95EC79CFBFB4220AF2B6E9D09551A1F2")
  },
  {
    TEXT("ntkrnlmp 5.1.2600.1106 (xpsp1.020828-1920)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("AAEF416AC44744F6B03A3B6259AE19881")
  },

  //
  // 5.1.2600.1138
  //
  {
    TEXT("ntkrnlpa 5.1.2600.1138 (xpsp2.020921-0842)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("EEC98437B8C64C0AA9316EBFF14CCFE65")
  },
  {
    TEXT("ntoskrnl 5.1.2600.1138 (xpsp2.020921-0842)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("AD5B6DD03E004D7BB0D355C42D29610E5")
  },

  //
  // 5.1.2600.1144
  //
  {
    TEXT("ntkrnlpa 5.1.2600.1144 (xpsp2.021108-1929)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("6DE07FC8872C47D5B22D20387B7F44273")
  },
  {
    TEXT("ntoskrnl 5.1.2600.1144 (xpsp2.021108-1929)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("31EE89B5DDB24922BB190478A63817EF3")
  },

  //
  // 5.1.2600.1149
  //
  {
    TEXT("ntkrnlpa 5.1.2600.1149 (xpsp2.021108-1929)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("6DE07FC8872C47D5B22D20387B7F44275")
  },
  {
    TEXT("ntoskrnl 5.1.2600.1149 (xpsp2.021108-1929)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("31EE89B5DDB24922BB190478A63817EF5")
  },

  //
  // 5.1.2600.1151
  //
  {
    TEXT("ntkrpamp 5.1.2600.1151 (xpsp2.030422-1633)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("04FB9A156FF44ECCA6EBCAE9617D8DB73")
  },
  {
    TEXT("ntkrnlpa 5.1.2600.1151 (xpsp2.030422-1633)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("2080ED7B99A74CD9B8A12C69A916BE483")
  },
  {
    TEXT("ntoskrnl 5.1.2600.1151 (xpsp2.030422-1633)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("FB1EDACE71FB4812A5D5132819D72E523")
  },
  {
    TEXT("ntkrnlmp 5.1.2600.1151 (xpsp2.030422-1633)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("785137BF3F3C484BA434E743DFECA8033")
  },

  //
  // 5.1.2600.1251
  //
  {
    TEXT("ntkrnlpa 5.1.2600.1251 (xpsp2.030721-1857)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("87DD8639AC5345A79BD89603C7833EC21")
  },
  {
    TEXT("ntoskrnl 5.1.2600.1251 (xpsp2.030721-1857)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("B9D1DA6CDD1846DAA468C6910C896F391")
  },

  //
  // 5.1.2600.1605
  //
  {
    TEXT("ntkrpamp 5.1.2600.1605 (xpsp2.040919-1003)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("5B1319B655B34CA7BC1AF71D96BDBE384")
  },
  {
    TEXT("ntkrnlpa 5.1.2600.1605 (xpsp2.040919-1003)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("86DDFCA28A1C44E9B068666F81AACCD34")
  },
  {
    TEXT("ntoskrnl 5.1.2600.1605 (xpsp2.040919-1003)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("E5465483EB2E4B5E9C35AC633A66377A2")
  },
  {
    TEXT("ntkrnlmp 5.1.2600.1605 (xpsp2.040919-1003)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("D9017BEDA05045C7AAEF1D639B5F01B44")
  },

  //
  // 5.1.2600.1634
  //
  {
    TEXT("ntkrpamp 5.1.2600.1634 (xpsp2.050301-1526)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("AD2CF35277144B7CA76B695F8A7946241")
  },
  {
    TEXT("ntkrnlpa 5.1.2600.1634 (xpsp2.050301-1526)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("4F10E20499CD454DA4E958DC6B7DC6151")
  },
  {
    TEXT("ntoskrnl 5.1.2600.1634 (xpsp2.050301-1526)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("8C0365A4579D46469E0B53A80062C0472")
  },
  {
    TEXT("ntkrnlmp 5.1.2600.1634 (xpsp2.050301-1526)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("49D26357C4BC4C9699A5260C5758DCCE1")
  },

  //
  // 5.1.2600.2055
  //
  {
    TEXT("ntkrpamp 5.1.2600.2055 (xpsp_sp2_beta1.031215-1745)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("272C8690E5A6453191A0FD2FD3B42AE11")
  },
  {
    TEXT("ntkrnlpa 5.1.2600.2055 (xpsp_sp2_beta1.031215-1745)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("D0AFF6ABC7A6455893037D64F445C3381")
  },
  {
    TEXT("ntoskrnl 5.1.2600.2055 (xpsp_sp2_beta1.031215-1745)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("EB6C6F5CEC9D457AAB82EC3264B6D2741")
  },
  {
    TEXT("ntkrnlmp 5.1.2600.2055 (xpsp_sp2_beta1.031215-1745)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("FF4F85D6C4A24DD79CA98CA57E89C5031")
  },

  //
  // 5.1.2600.2096
  //
  {
    TEXT("ntkrnlpa 5.1.2600.2096 (xpsp_sp2_rc1.040311-2315)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("3FD0C106E6C64D489CB5408DE20BB2A31")
  },
  {
    TEXT("ntoskrnl 5.1.2600.2096 (xpsp_sp2_rc1.040311-2315)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("9996D1AF67964E6A947A9EA33EC8B9112")
  },

  //
  // 5.1.2600.2149
  //
  {
    TEXT("ntkrnlpa 5.1.2600.2149 (xpsp_sp2_rc2.040610-1520)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("BF484640AF2249E5B9024220F47FC8071")
  },
  {
    TEXT("ntoskrnl 5.1.2600.2149 (xpsp_sp2_rc2.040610-1520)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("4B9A9350E82F4127864C8961EC3B77E22")
  },

  //
  // 5.1.2600.2180
  //

  {
    TEXT("ntkrnlpa 5.1.2600.2180 (xpsp_sp2_rtm.040803-2158)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("BD8F451F3E754ED8A34B50560CEB08E31")
  },
  {
    TEXT("ntkrnlmp 5.1.2600.2180 (xpsp_sp2_rtm.040803-2158)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("7DE39A3E89DA4B378B95A09FA3A6398C2")
  }, 
  {
    TEXT("ntkrpamp 5.1.2600.2180 (xpsp_sp2_rtm.040803-2158)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("C40DD53A8D3D4AE3A24CE6BE866649C91")
  },
  {
    TEXT("ntoskrnl 5.1.2600.2180 (xpsp_sp2_rtm.040803-2158)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("8592B6763F34476B9BB560395A383F962")
  },

  //
  // 5.1.2600.2507
  //
  {
    TEXT("ntkrnlpa 5.1.2600.2507 (xpsp.040806-1825)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("D3C6623EA2154FF3B7FE7B5650EA03462")
  },
  {
    TEXT("ntoskrnl 5.1.2600.2507 (xpsp.040806-1825)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("F9574CF72DB743B1AEBBF083CF6CD5832")
  },

  //
  // 5.1.2600.2573
  //
  {
    TEXT("ntkrnlpa 5.1.2600.2573 (xpsp.041130-1728)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("22D47F5E8FB544849C55A3267A02F7AB1")
  },
  {
    TEXT("ntoskrnl 5.1.2600.2573 (xpsp.041130-1728)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("1BFC5047E16A49D483AA4F6AD131AE7D2")
  },

  //
  // 5.1.2600.2622
  //
  {
    TEXT("ntkrpamp 5.1.2600.2622 (xpsp_sp2_gdr.050301-1519)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("430480FAAC4F4A45980B99443EDC145E1")
  },  
  {
    TEXT("ntkrnlpa 5.1.2600.2622 (xpsp_sp2_gdr.050301-1519)"), 
    TEXT("ntkrnlpa.pdb"),
    TEXT("89C2A9EB56A74E2D8269AFD1D835BA331")
  }, 
  {
    TEXT("ntoskrnl 5.1.2600.2622 (xpsp_sp2_gdr.050301-1519)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("32962337F0F646388B39535CD8DD70E82")
  }, 
  {
    TEXT("ntkrnlmp 5.1.2600.2622 (xpsp_sp2_gdr.050301-1519)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("AA1EE1B2A63A4232A379F3EFDDC4CFE82")
  }, 

  //
  // 5.1.2600.2622
  //
  {
    TEXT("ntkrpamp 5.1.2600.2622 (xpsp.050301-1521)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("EE13F4FFB97343489F63767D2E72F4741")
  }, 
  {
    TEXT("ntkrnlpa 5.1.2600.2622 (xpsp.050301-1521)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("8FB67EFA263E45C4BEF1AC0748EC9EB01")
  }, 
  {
    TEXT("ntoskrnl 5.1.2600.2622 (xpsp.050301-1521)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("012E81B8E0724418A1E96DD7F1C5CB9F2")
  }, 
  {
    TEXT("ntkrnlmp 5.1.2600.2622 (xpsp.050301-1521)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("1F623A3A03514FBA84802D392AFDDE182")
  }, 

  //
  // 5.1.2600.2643
  //
  {
    TEXT("ntkrpamp 5.1.2600.2643 (xpsp.050329-1536)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("F34F1BF50056422FB0FE176944516D4A1")
  },
  {
    TEXT("ntkrnlpa 5.1.2600.2643 (xpsp.050329-1536)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("6CB8826CEEE24F4A88484F5DAA09A6E11")
  },  
  {
    TEXT("ntoskrnl 5.1.2600.2643 (xpsp.050329-1536)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("9F2528E50F6E473796E007462C77D4E82")
  }, 
  {
    TEXT("ntkrnlmp 5.1.2600.2643 (xpsp.050329-1536)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("8A840CDB24D446469499CC12974C0D322")
  },  

  //
  // 5.1.2600.2670
  //
  {
    TEXT("ntkrnlpa 5.1.2600.2670 (xpsp.050504-1703)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("02EDF4F0DCB84D8CB8F8DD0DEED32A121")
  },  
  {
    TEXT("ntoskrnl 5.1.2600.2670 (xpsp.050504-1703)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("7B85A57143994DADBECA27768E3068982")
  }, 

  //
  // 5.1.2600.2705
  //
  {
    TEXT("ntkrpamp 5.1.2600.2705 (xpsp.050622-1524)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("1BBE06CABB4C4965B304101D416846321")
  }, 
  {
    TEXT("ntkrnlmp 5.1.2600.2705 (xpsp.050622-1524)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("46BA5C69C3A2424D99AE8F7B790630C82")
  },  

  //
  // 5.1.2600.2765
  //
  {
    TEXT("ntkrpamp 5.1.2600.2765 (xpsp.050928-1517)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("93B3151FBA1F444E921B0B7AF2BADA5A1")
  }, 
  {
    TEXT("ntkrnlpa 5.1.2600.2765 (xpsp.050928-1517)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("CC2DE018A01244D4832AF532340DCAC41")
  }, 
  {
    TEXT("ntoskrnl 5.1.2600.2765 (xpsp.050928-1517)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("7DEB5F662C1B4675A79BE082B317F5402")
  }, 
  {
    TEXT("ntkrnlmp 5.1.2600.2765 (xpsp.050928-1517)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("040335E8D8E841DD9729CF44B21C11792")
  }, 

  //
  // 5.1.2600.2774
  //
  {
    TEXT("ntkrpamp 5.1.2600.2774 (xpsp.051011-1528)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("9BEFAFFECB0B4E7684D537E7896F1D091")
  }, 
  {
    TEXT("ntkrnlpa 5.1.2600.2774 (xpsp.051011-1528)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("4A60D40C68D74A7A91F60EB5C4B91D1B1")
  }, 
  {
    TEXT("ntoskrnl 5.1.2600.2774 (xpsp.051011-1528)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("53D901D8DB1340B4B49A8F1155E449E22")
  },  
  {
    TEXT("ntkrnlmp 5.1.2600.2774 (xpsp.051011-1528)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("C5C5A2CF44924714BD7B4B42F2B227422")
  },

  //
  // 5.1.2600.2780
  //

  {
    TEXT("ntkrnlpa 5.1.2600.2780 (xpsp.051019-1519)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("36305F504228465EB4BCD5C83EF15B171")
  },
  {
    TEXT("ntoskrnl 5.1.2600.2780 (xpsp.051019-1519)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("1B090CFFA6AE431E9B1C7A5933A65D742")
  }, 

  //
  // 5.1.2600.2845
  //
  {
    TEXT("ntkrpamp 5.1.2600.2845 (xpsp.060210-1526)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("1AFF284D7C434F43979B2AE28D1E4EE21")
  }, 
  {
    TEXT("ntkrnlpa 5.1.2600.2845 (xpsp.060210-1526)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("A6C25E430DA54B1AA0C2DBA0F3C8FC3E1")
  },
  {
    TEXT("ntoskrnl 5.1.2600.2845 (xpsp.060210-1526)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("71B34FCB62504F4EAEEEFF268CC10DD72")
  }, 
  {
    TEXT("ntkrnlmp 5.1.2600.2845 (xpsp.060210-1526)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("4289FD8BCB254A3CA5A2FF206D2E535D2")
  }, 

  //
  // 5.1.2600.2853 xpsp_sp2
  //
  {
    TEXT("ntkrpamp 5.1.2600.2853 (xpsp_sp2_gdr.060220-1746)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("AD416A59B488487E9F2D08FCC806B0581")
  }, 
  {
    TEXT("ntkrnlpa 5.1.2600.2853 (xpsp_sp2_gdr.060220-1746)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("1EBA29264BF540EEA058A9992268B8801")
  },
  {
    TEXT("ntoskrnl 5.1.2600.2853 (xpsp_sp2_gdr.060220-1746)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("6939A22A49B34CCC93C88B9F23924AB72")
  }, 
  {
    TEXT("ntkrnlmp 5.1.2600.2853 (xpsp_sp2_gdr.060220-1746)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("9B934D5224B84CB396AF163480C147822")
  }, 

  //
  // 5.1.2600.2853 xpsp
  //
  {
    TEXT("ntkrnlpa 5.1.2600.2853 (xpsp.060220-1751)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("85545D4AB9AE40CF9807022CA7D94F391")
  },
  {
    TEXT("ntoskrnl 5.1.2600.2853 (xpsp.060220-1751)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("97206FCD45F4469C8C8F9447DE8ECDE12")
  },

  //
  // 5.1.2600.2868
  //
  {
    TEXT("ntkrpamp 5.1.2600.2868 (xpsp.060315-1524)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("F2331C35CF85412890196BB85BD388E01")
  },
  {
    TEXT("ntkrnlpa 5.1.2600.2868 (xpsp.060315-1524)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("23C083B907B0431CA019DA7F5E42A2671")
  },
  {
    TEXT("ntoskrnl 5.1.2600.2868 (xpsp.060315-1524)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("795D57E8CCA7486387098DEFE009772C2")
  },  
  {
    TEXT("ntkrnlmp 5.1.2600.2868 (xpsp.060315-1524)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("982C42F9C9094811B1F90AA8857945CE2")
  }, 

  //
  // 5.1.2600.2885
  //
  {
    TEXT("ntkrpamp 5.1.2600.2885 (xpsp.060411-1541)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("DC1B268F6995464E8049D76F1C09A1911")
  },
  {
    TEXT("ntkrnlpa 5.1.2600.2885 (xpsp.060411-1541)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("B6C8E62983CF4D248EB7B27852128EA71")
  },
  {
    TEXT("ntoskrnl 5.1.2600.2885 (xpsp.060411-1541)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("3267232A6DEE4A1CB588270118C75F062")
  },
  {
    TEXT("ntkrnlmp 5.1.2600.2885 (xpsp.060411-1541)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("B54BA915B1E341E99E6C33B280BE83512")
  },   

  //
  // 5.1.2600.3014
  //
  {
    TEXT("ntkrpamp 5.1.2600.3014 (xpsp.061012-0254)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("974AD9660ACF4598B8E26A0B6227108F1")
  },
  {
    TEXT("ntkrnlpa 5.1.2600.3014 (xpsp.061012-0254)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("14E65FC367CD4D2A83264A1CFEB2E7751")
  },
  {
    TEXT("ntoskrnl 5.1.2600.3014 (xpsp.061012-0254)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("F8DE4616591E4A8683129E2A1464499C2")
  },  
  {
    TEXT("ntkrnlmp 5.1.2600.3014 (xpsp.061012-0254)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("E66FB71131C245278B98AE4B5472BFB52")
  },

  //
  // 5.1.2600.3023 (xpsp_sp2_qfe)
  //
  {
    TEXT("ntkrpamp 5.1.2600.3023 (xpsp_sp2_qfe.061030-0020)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("D06267DBA44B4577ACBEFB98D0A2A1501")
  },
  {
    TEXT("ntkrnlpa 5.1.2600.3023 (xpsp_sp2_qfe.061030-0020)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("41A9DC76628943EA8563E538BE8682221")
  },
  {
    TEXT("ntoskrnl 5.1.2600.3023 (xpsp_sp2_qfe.061030-0020)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("89017B70BAA9436FB806242D31DC30602")
  },
  {
    TEXT("ntkrnlmp 5.1.2600.3023 (xpsp_sp2_qfe.061030-0020)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("68199A72D5A64F29AB7AF5B3AD1E8ECB2")
  },

  //
  // 5.1.2600.3023 (xpsp_sp2_gdr)
  //
  {
    TEXT("ntkrpamp 5.1.2600.3023 (xpsp_sp2_gdr.061030-0016)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("17687859CFC64F1AB086A2FDF2B9337D1")
  },
  {
    TEXT("ntkrnlmp 5.1.2600.3023 (xpsp_sp2_gdr.061030-0016)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("457794883C7943C9B06ED499F6059B602")
  },

  //
  // 5.1.2600.3051 (xpsp_sp2_qfe)
  //
  {
    TEXT("ntkrpamp 5.1.2600.3051 (xpsp_sp2_qfe.061219-0311)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("F67236BB349E4666B96B5D6E57461D161")
  },
  {
    TEXT("ntkrnlpa 5.1.2600.3051 (xpsp_sp2_qfe.061219-0311)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("E4A93C3F8FC744B3816664693BB727111")
  },
  {
    TEXT("ntoskrnl 5.1.2600.3051 (xpsp_sp2_qfe.061219-0311)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("6E9A14FCD68D4E888B7A893EA7A2645A2")
  },  
  {
    TEXT("ntkrnlmp 5.1.2600.3051 (xpsp_sp2_qfe.061219-0311)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("53A4AEB8EF0A407FACC9D8DA4BE5284D2")
  },  

  //
  // 5.1.2600.3051 (xpsp_sp2_gdr)
  //
  {
    TEXT("ntkrpamp 5.1.2600.3051 (xpsp_sp2_gdr.061219-0316)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("E59C275A6E4D4461BBFE8C54DC187B341")
  },
  {
    TEXT("ntkrnlpa 5.1.2600.3051 (xpsp_sp2_gdr.061219-0316)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("A85A022656B24A8587F90BF0C2ED15011")
  },
  {
    TEXT("ntoskrnl 5.1.2600.3051 (xpsp_sp2_gdr.061219-0316)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("3F158FA7B78E451C9756DF117E5E8A1E2")
  },
  {
    TEXT("ntkrnlmp 5.1.2600.3051 (xpsp_sp2_gdr.061219-0316)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("33AD26D796B84CB896736344DA9D043D2")
  },

  //
  // 5.1.2600.3093 (xpsp_sp2_qfe)
  //
  {
    TEXT("ntkrpamp 5.1.2600.3093 (xpsp_sp2_qfe.070227-2300)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("176A183ABE1E46FEBCEFCCE79427EF8F1")
  },
  {
    TEXT("ntkrnlpa 5.1.2600.3093 (xpsp_sp2_qfe.070227-2300)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("CF7B79A8CE864FCF8ABF248F0B69F4C91")
  },
  {
    TEXT("ntoskrnl 5.1.2600.3093 (xpsp_sp2_qfe.070227-2300)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("1A3C32DE71A243C1AB6FC693C98B59C32")
  },
  {
    TEXT("ntkrnlmp 5.1.2600.3093 (xpsp_sp2_qfe.070227-2300)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("8474ECD7D511433E876CF8AE18D67E2C2")
  },  

  //
  // 5.1.2600.3093 (xpsp_sp2_gdr)
  //
  {
    TEXT("ntkrpamp 5.1.2600.3093 (xpsp_sp2_gdr.070227-2254)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("966DF78E558F483199141B029DF5A9D51")
  },
  {
    TEXT("ntkrnlpa 5.1.2600.3093 (xpsp_sp2_gdr.070227-2254)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("F612363DB38C423CB08559DDBCA9F2F71")
  },
  {
    TEXT("ntoskrnl 5.1.2600.3093 (xpsp_sp2_gdr.070227-2254)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("A3930799CDF74A3CA818CCF481C59BAB2")
  }, 
  {
    TEXT("ntkrnlmp 5.1.2600.3093 (xpsp_sp2_gdr.070227-2254)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("7627B1ADA0F5436AAA5DB5B9B2C11FFF2")
  },

  //
  // 5.2.3790.0
  //
  {
    TEXT("ntkrpamp 5.2.3790.0 (srv03_rtm.030324-2048)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("0FE0EA646FD64F91B512E45B9FCB61C81")
  },
  {
    TEXT("ntkrnlpa 5.2.3790.0 (srv03_rtm.030324-2048)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("3E5EC2822A12407CAE564E6D6D0619B31")
  },
  {
    TEXT("ntoskrnl 5.2.3790.0 (srv03_rtm.030324-2048)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("112679F166D6449394EFC30950DE9E032")
  },
  {
    TEXT("ntkrnlmp 5.2.3790.0 (srv03_rtm.030324-2048)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("4E4A894DD1A64BC3ADFEA71F18E293642")
  },

  //
  // 5.2.3790.280 (srv03_gdr)
  //
  {
    TEXT("ntkrpamp 5.2.3790.280 (srv03_gdr.050225-1827)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("E6557729FE244544B9F0FE18878C7E671")
  },
  {
    TEXT("ntkrnlpa 5.2.3790.280 (srv03_gdr.050225-1827)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("69D0093E45FE41F5BA41F693D249E0511")
  },
  {
    TEXT("ntoskrnl 5.2.3790.280 (srv03_gdr.050225-1827)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("39C0C738C4EA49F7A0FBC098FCF6153C2")
  },
  {
    TEXT("ntkrnlmp 5.2.3790.280 (srv03_gdr.050225-1827)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("54E9775FEC794E8C8B8EEDD84A06E7A02")
  },

  //
  // 5.2.3790.280 (srv03_qfe)
  //
  {
    TEXT("ntkrpamp 5.2.3790.280 (srv03_qfe.050225-1637)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("35583D27512F43C3BB85C59E392D31411")
  },
  {
    TEXT("ntkrnlmp 5.2.3790.280 (srv03_qfe.050225-1637)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("E0408A59CF1D4ABEA81C2A09C5DC9A022")
  },

  //
  // 5.2.3790.1830
  //
  {
    TEXT("ntkrpamp 5.2.3790.1830 (srv03_sp1_rtm.050324-1447)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("FEC480982D1145E696432CBBD9BC2C831")
  },
  {
    TEXT("ntkrnlpa 5.2.3790.1830 (srv03_sp1_rtm.050324-1447)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("80A87123E83C40579E8319E5DB7B523C1")
  },
  {
    TEXT("ntoskrnl 5.2.3790.1830 (srv03_sp1_rtm.050324-1447)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("4106003FF97D4BCBA99245BF2172A8C12")
  },
  {
    TEXT("ntkrnlmp 5.2.3790.1830 (srv03_sp1_rtm.050324-1447)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("D11928D0A382448AA96E545C81E4DD172")
  },

  //
  // 5.2.3790.2438
  //
  {
    TEXT("ntkrpamp 5.2.3790.2438 (srv03_sp1_qfe.050504-1733)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("8C08A30DAE7F49DD9D1F68B48D5DA1B61")
  },
  {
    TEXT("ntkrnlmp 5.2.3790.2438 (srv03_sp1_qfe.050504-1733)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("EC336E77A94E4FBBBDF9A7006199B12C2")
  },

  //
  // 5.2.3790.2794
  //
  {
    TEXT("ntkrpamp 5.2.3790.2794 (srv03_sp1_qfe.060915-2230)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("468CB3AE87CE4D04AB5A72558B6154881")
  },
  {
    TEXT("ntkrnlmp 5.2.3790.2794 (srv03_sp1_qfe.060915-2230)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("555FF7336E014AFAACD90D11B72860DD2")
  },

  //
  // 5.2.3790.2825
  //
  {
    TEXT("ntkrnlpa 5.2.3790.2825 (srv03_sp2_rc.061103-1303)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("28DA1EDE55594F6480E5D49A90930E061")
  },
  {
    TEXT("ntoskrnl 5.2.3790.2825 (srv03_sp2_rc.061103-1303)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("0E7EE149C732419988C899921614C4752")
  },

  //
  // 5.2.3790.2894
  //
  {
    TEXT("ntkrpamp 5.2.3790.2894 (srv03_sp1_gdr.070304-2232)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("902FD30EE82E4C8AA8448B8AF0534E8E1")
  },
  {
    TEXT("ntkrnlpa 5.2.3790.2894 (srv03_sp1_gdr.070304-2232)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("48CAAE1E2B76426CB36005A90D0894DC1")
  },
  {
    TEXT("ntoskrnl 5.2.3790.2894 (srv03_sp1_gdr.070304-2232)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("5BB56E6E69FA42808DA8A9CC031385452")
  },
  {
    TEXT("ntkrnlmp 5.2.3790.2894 (srv03_sp1_gdr.070304-2232)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("616447EA59A34518878A53CE9AC9CF6A2")
  },

  //
  // 5.2.3790.3959
  //
  {
    TEXT("ntkrpamp 5.2.3790.3959 (srv03_sp2_rtm.070216-1710)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("5A50E2594F3E433ABAE37E3692A3CCE61")
  },
  {
    TEXT("ntkrnlpa 5.2.3790.3959 (srv03_sp2_rtm.070216-1710)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("4121E0AD95474F849EBDDF280C7E498D1")
  },
  {
    TEXT("ntoskrnl 5.2.3790.3959 (srv03_sp2_rtm.070216-1710)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("6CB8DB5C933549D480D86C017861E13D2")
  },
  {
    TEXT("ntkrnlmp 5.2.3790.3959 (srv03_sp2_rtm.070216-1710)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("DA4D2E91B9E04DF9A447976D7EB8BECD2")
  },

  //
  // 5.2.3790.4035
  //
  {
    TEXT("ntkrpamp 5.2.3790.4035 (srv03_sp2_gdr.070304-2240)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("52A81696FB5B432AB0B1B46297F104D31")
  },
  {
    TEXT("ntkrnlpa 5.2.3790.4035 (srv03_sp2_gdr.070304-2240)"),
    TEXT("ntkrnlpa.pdb"),
    TEXT("BB346E8288E5412A8AF4763DF1E71B7C1")
  },
  {
    TEXT("ntoskrnl 5.2.3790.4035 (srv03_sp2_gdr.070304-2240)"),
    TEXT("ntoskrnl.pdb"),
    TEXT("AFCC59458F254735B9461CAFAC8C037D2")
  },
  {
    TEXT("ntkrnlmp 5.2.3790.4035 (srv03_sp2_gdr.070304-2240)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("A91CA63E49A840F4A50509F90ADE10D52")
  },

  //
  // 6.0.5600.16384
  //
  {
    TEXT("ntkrpamp 6.0.5600.16384 (vista_rc1.060829-2230)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("A60B2B6C061F47FF8BBADF2D2330D1322")
  },
  {
    TEXT("ntkrnlmp 6.0.5600.16384 (vista_rc1.060829-2230)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("1A11D2890F724D0986991D2EB57DCDE12")
  },   

  //
  // 6.0.5744.16384
  //
  {
    TEXT("ntkrpamp 6.0.5744.16384 (vista_rtm_edw.061003-1945)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("6FB5B7D5D7C04735B3DC168622497B2B2")
  },
  {
    TEXT("ntkrnlmp 6.0.5744.16384 (vista_rtm_edw.061003-1945)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("6C0BE07BB9F040E6A9B6B6C0B4BC1E0B2")
  }, 

  //
  // 6.0.6000.16386
  //
  {
    TEXT("ntkrpamp 6.0.6000.16386 (vista_rtm.061101-2205)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("FD50D285751D4684938604B2CC1B41682")
  },
  {
    TEXT("ntkrnlmp 6.0.6000.16386 (vista_rtm.061101-2205)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("8EE03D077FB748338312523DCC42D1692")
  }, 

  //
  // 6.0.6001.16510
  //
/*
  {
    TEXT("ntkrpamp 6.0.6001.16510 (longhorn_beta3.070417-1740)"),
    TEXT("ntkrpamp.pdb"),
    TEXT("747FAD32B64E40859AB1CF0702CD66342")
  },
  {
    TEXT("ntkrnlmp 6.0.6001.16510 (longhorn_beta3.070417-1740)"),
    TEXT("ntkrnlmp.pdb"),
    TEXT("7834D3BE68FA4627B3EC3F878030A23E2")
  }, 
*/
} ;

#define VERSION_COUNT arraysize(aVersions)



ULONG _GetFileSize (LPCTSTR szFile)
{
  ULONG		nFileSize ;
  HANDLE	hFile ;

  hFile = CreateFile (szFile, GENERIC_READ, FILE_SHARE_READ, 
		      NULL, OPEN_EXISTING, 0, NULL ); 
  
  nFileSize = GetFileSize (hFile, NULL) ; 
  
  CloseHandle (hFile) ;

  return nFileSize ;
}

BOOL GetFunctionsAddressOfVersion (VERSION_ENTRY * pVersion)
{
  HANDLE	hProcess = GetCurrentProcess () ;
  DWORD		nFileSize ;
  DWORD		nBaseAddr = 0x804DE000 ;
  IMAGEHLP_SYMBOL sym ;
  TCHAR		szSymbolFile[MAX_PATH] ;
  int		i ;
  BOOL		bSuccess ;
  int		nGoodSymbols = 0 ;
  int		nWrongSymbols = 0 ;

  _tcscpy (szSymbolFile, szPrefix) ;
  _tcscat (szSymbolFile, TEXT("\\")) ;
  _tcscat (szSymbolFile, pVersion->szSymFilename) ;
  _tcscat (szSymbolFile, TEXT("\\")) ;
  _tcscat (szSymbolFile, pVersion->szSymSignature) ;
  _tcscat (szSymbolFile, TEXT("\\")) ;
  _tcscat (szSymbolFile, pVersion->szSymFilename) ;

  if( 0xFFFFFFFF==GetFileAttributes(szSymbolFile) )
    {
      _ftprintf (stderr, TEXT("File %s not found\n"), szSymbolFile) ;
      return FALSE ;     
    }


  bSuccess = SymInitialize (hProcess, NULL, FALSE) ;
  
  if( ! bSuccess )
    {
      _ftprintf (stderr, TEXT("SymInitialize failed (error=%lu)\n"), GetLastError()) ;
      return FALSE ;
    }

  nFileSize = _GetFileSize (szSymbolFile) ;
 
  SymSetOptions (0x0800|SymGetOptions()) ;
  
  bSuccess = SymLoadModule (hProcess, NULL,
			    szSymbolFile, NULL, 
			    nBaseAddr, nFileSize) ;

  if( ! bSuccess )
    {
      _tprintf (TEXT("SymLoadModule failed (error=%lu)\n"), GetLastError()) ;
      SymCleanup (hProcess) ;
      return FALSE ;
    }

  for( i=0 ; i<arraysize(aFunctionNames) ; i++ )
    {
      sym.SizeOfStruct = sizeof(sym) ;
      sym.Size = 0 ;
      sym.MaxNameLength = 1 ;
      sym.Address = 0 ;
      
      bSuccess = SymGetSymFromName (hProcess, (LPTSTR)aFunctionNames[i], &sym) ;
      
      if( bSuccess )
	pVersion->aFunctions[i] = (void*)( sym.Address - nBaseAddr ) ;
      else
	pVersion->aFunctions[i] = NULL ;
      
      if( bSuccess ) 
	nGoodSymbols++ ;
      else
	nWrongSymbols++ ;	
    }
  
  SymUnloadModule (hProcess, nBaseAddr) ;
  
  SymCleanup (hProcess) ;

  if( nGoodSymbols == 0 )
    {
      printf ("Symbols format is not supported\n") ;
      pVersion->bDisabled = TRUE ;
      return FALSE ;
    }
  
  if( nWrongSymbols > 2 )
    {
      printf ("%d symbols not found\n", nWrongSymbols) ;
      pVersion->bDisabled = TRUE ;
      return FALSE ;
    }

  return TRUE ;
}


HINTERNET hSession ;
HINTERNET hConnect ;
HINTERNET hRequest ;

BOOL ConnectToSymbolServer ()
{
  LPCTSTR szAgent = TEXT("Microsoft-Symbol-Server/6.4.0007.1") ;
  LPCTSTR szServerName = TEXT("msdl.microsoft.com") ;
  UINT	 nServerPort = 80 ;
  LPCTSTR szUsername = NULL ;
  LPCTSTR szPassword = NULL ;
 
  hSession = InternetOpen (szAgent, INTERNET_OPEN_TYPE_PRECONFIG, NULL, NULL, 0) ;
  
  if( ! hSession ) {
    _tprintf (TEXT("InternetOpen failed\n")) ;
    return FALSE ;
  }

  hConnect = InternetConnect (hSession, szServerName, nServerPort,
			     szUsername, szPassword,
			     INTERNET_SERVICE_HTTP, 0, 0) ;

  if( ! hConnect ) {
      _tprintf (TEXT("InternetConnect failed\n")) ;
      return FALSE ;
    }

  return TRUE ;
}

BOOL DisconnectFromSymbolServer ()
{
  InternetCloseHandle (hRequest) ;
  InternetCloseHandle (hConnect) ;
  InternetCloseHandle (hSession) ;

  return TRUE ;
}

BOOL DownloadFile (LPCTSTR szFileOnServer, LPCTSTR szLocalFile)
{
  LPCTSTR szHttpVersion = "HTTP/1.1" ;
  LPCTSTR szReferer = TEXT("www.google.com") ;

  DWORD dwContentLength ;
  BOOL	bSuccess ;
  char pBuffer[32] ;
  DWORD dwBufferSize = 32 ;
  DWORD dwBytesRead ;
  char * pContent ;
  FILE * fp ;

  //  printf ("  downloading %s...\n", szFileOnServer) ;

  hRequest = HttpOpenRequest (hConnect, TEXT("GET"), szFileOnServer,
			      szHttpVersion, szReferer, NULL, 
			      INTERNET_FLAG_RELOAD|INTERNET_FLAG_NO_UI,0) ;
  
  if( ! hRequest ) {
    _tprintf (TEXT("HttpOpenRequest failed\n")) ;
    return FALSE ;
  }
  
  if( ! HttpSendRequest (hRequest, NULL, 0, 0, 0) ) {
    _tprintf (TEXT("HttpSendRequest failed (error=%lu)\n"), GetLastError()) ;
    return FALSE ;
  }
  
  dwBufferSize = 32 ;
  bSuccess = HttpQueryInfo(hRequest, HTTP_QUERY_STATUS_CODE,
			   pBuffer, &dwBufferSize, NULL) ;
  
  if( ! bSuccess ) {
    _tprintf (TEXT("HttpQueryInfo failed\n")) ;
    return FALSE ;
  }

  if( pBuffer[0]!='2' || pBuffer[1]!='0' || pBuffer[2]!='0' )
    {
      _tprintf (TEXT("File not found\n")) ;
      return FALSE ;
    }
  
  dwBufferSize = 32 ;
  bSuccess = HttpQueryInfo(hRequest, HTTP_QUERY_CONTENT_LENGTH,
			   pBuffer, &dwBufferSize, NULL) ;
  
  if( ! bSuccess ) {
    _tprintf (TEXT("HttpQueryInfo failed\n")) ;
    return FALSE ;
  }

  dwContentLength = (DWORD)atol(pBuffer) ;

  pContent = (char*) malloc (dwContentLength) ; 

  bSuccess = InternetReadFile(hRequest, pContent,
			      dwContentLength, &dwBytesRead);
  
  if( ! bSuccess ) {
    _tprintf (TEXT("InternetReadFile failed\n")) ;
    free (pContent) ;
    return FALSE ;
  }

  fp = _tfopen (szLocalFile, TEXT("wb")) ;
  fwrite (pContent, dwBytesRead, 1, fp) ;
  fclose (fp) ;
  
  free (pContent) ; 

  return TRUE ;
}

BOOL DownloadAndDecompress (LPCTSTR szFileOnServer, LPCTSTR szLocalFile)
{
  TCHAR szCompOnServer[256] ;
  TCHAR szCompLocal[256] ;

  UINT	nError ;
  
  strcpy (szCompOnServer, szFileOnServer) ;
  szCompOnServer[_tcslen(szCompOnServer)-1] = TEXT('_') ;

  strcpy (szCompLocal, szLocalFile) ;
  szCompLocal[_tcslen(szCompLocal)-1] = TEXT('_') ;

  if( ! DownloadFile (szCompOnServer,szCompLocal) )
    return FALSE ;

  nError = SetupDecompressOrCopyFile (szCompLocal, szLocalFile, NULL) ;
  if( nError != 0 )
    {
      _tprintf (TEXT("\nSetupDecompressOrCopyFile failed\n(src=%s, dst=%s, error=%d)\n"), szCompLocal, szLocalFile, nError) ;
      DeleteFile (szCompLocal) ;
      return FALSE ;
    }  

  DeleteFile (szCompLocal) ;
  
  return TRUE ;
}


BOOL GetDbgInfo (LPCTSTR szDbgFile, LPTSTR szPdbFilename, LPTSTR szPdbSignature)
{
  FILE * fp ;
  UINT nFileSize ;
  UINT nBufferSize ;
  BOOL bFound ;
  UINT i ;
  DWORD* pBuffer ;

  fp = fopen (szDbgFile, TEXT("rb")) ;
  if( ! fp ) {
    printf ("Failed to open %s\n", szDbgFile) ;
    return FALSE ;
  }

  nFileSize = _filelength(fileno(fp)) ;
  nBufferSize = nFileSize ;
  
  pBuffer = malloc (nBufferSize) ;

  if( 1!=fread (pBuffer, nBufferSize, 1, fp) )
    {
      printf ("Failed to read %s\n", szDbgFile) ;
      fclose (fp) ;
      return FALSE ;
    }
      
  fclose (fp) ;  

  bFound = FALSE ;

  for( i=0 ; i<nBufferSize/4 && !bFound ; i++ )
    {
      if( pBuffer[i]==0x3031424e )
	{
	  sprintf (szPdbSignature, TEXT("%08lX%lX"),
		   pBuffer[i+2], pBuffer[i+3]) ;
	  strcpy (szPdbFilename, (char*)&pBuffer[i+4]) ;
	  bFound = TRUE ;
	}
    }

  if( ! bFound )
    printf ("Failed to find info in %s\n", szDbgFile) ;

  return bFound ;
}

BOOL DownloadSymFile (LPCSTR szFile, LPCTSTR szSignature)
{
  TCHAR szObjectName[256] ;
  TCHAR szOutputFile[256] ;

  _stprintf (szObjectName, TEXT("/download/symbols/%s/%s/%s"),
	     szFile, szSignature, szFile) ;

  _tcscpy (szOutputFile, szPrefix) ;
  _tmkdir (szOutputFile) ;

  _tcscat (szOutputFile, TEXT("\\")) ;
  _tcscat (szOutputFile, szFile) ;
  _tmkdir (szOutputFile) ;

  _tcscat (szOutputFile, TEXT("\\")) ;
  _tcscat (szOutputFile, szSignature) ;
  _tmkdir (szOutputFile) ;

  _tcscat (szOutputFile, TEXT("\\")) ;
  _tcscat (szOutputFile, szFile) ;

  if( ! DownloadAndDecompress (szObjectName, szOutputFile) )
    return FALSE ;

  if( !_tcsicmp(PathFindExtension(szFile),TEXT(".dbg") )  )
    {
      TCHAR szPdbFilename[256] ;
      TCHAR szPdbSignature[32] ;
      TCHAR szLocalPdbFile[256] ;

      if( !GetDbgInfo (szOutputFile, szPdbFilename, szPdbSignature) )
	return FALSE ;

      strcpy (szLocalPdbFile, szOutputFile) ;
      strcpy (PathFindFileName(szLocalPdbFile), szPdbFilename) ;
      
      _stprintf (szObjectName, TEXT("/download/symbols/%s/%s/%s"),
		 szPdbFilename, szPdbSignature, szPdbFilename) ;

      if( !DownloadAndDecompress (szObjectName, szLocalPdbFile) )
	return FALSE ;
    }
  
  _tprintf (TEXT("OK\n")) ;
  
  return TRUE ;
}

BOOL IsSymFilePresent (LPCTSTR szFilename, LPCTSTR szSignature)
{
  TCHAR szFile[256] ;

  _stprintf (szFile, TEXT("%s\\%s\\%s\\%s"),
	     szPrefix, szFilename, szSignature, szFilename) ;

  //printf ("\nCheck file %s\n", szFile) ;

  if( 0xFFFFFFFF == GetFileAttributes(szFile) )
    return FALSE ;

  if( !_tcsicmp(PathFindExtension(szFilename),TEXT(".dbg") )  )
    {
      TCHAR szPdbFilename[256] ;
      TCHAR szPdbSignature[32] ;

      if( !GetDbgInfo (szFile, szPdbFilename, szPdbSignature) )
	return FALSE ;

      strcpy (PathFindFileName(szFile), szPdbFilename) ;

      //printf ("Check file %s\n", szFile) ;

      if( 0xFFFFFFFF == GetFileAttributes(szFile) )
	return FALSE ;
    }

  return TRUE ;
}



BOOL DownloadMissingFiles ()
{
  int i ;

  _tprintf (TEXT("Download files\n"
		 "--------------\n")) ;

  ConnectToSymbolServer () ;
	    
  for( i=0 ; i<VERSION_COUNT ; i++ )
    {
      _tprintf (TEXT("%s... "), aVersions[i].szName) ;     

      if( ! IsSymFilePresent(aVersions[i].szSymFilename,aVersions[i].szSymSignature) )
	{
	  if( ! DownloadSymFile (aVersions[i].szSymFilename, aVersions[i].szSymSignature) )
	    aVersions[i].bDisabled = TRUE ;
	}
      else
	{
	  _tprintf (TEXT("Skipped\n")) ;
	}
    }

  DisconnectFromSymbolServer () ;

  _tprintf (TEXT("\n")) ;

  return TRUE ;
}

BOOL ReadSymbolFiles ()
{
  int i ;

  _tprintf (TEXT("Read symbols\n"
		 "------------\n")) ;
	    
  for( i=0 ; i<VERSION_COUNT ; i++ )
    {
      _tprintf (TEXT("%s... "), aVersions[i].szName) ;

      if( aVersions[i].bDisabled )
	{
	  _tprintf (TEXT("Skipped\n")) ;
	  continue ;
	}

      if( GetFunctionsAddressOfVersion(&aVersions[i]) )
	  _tprintf (TEXT("OK\n")) ;
    }

  _tprintf (TEXT("\n")) ;

  return TRUE ;
}


BOOL RestoreMissingSymbols ()
{
  int i, j ;
  HSYMFILE hSymFile ;

  _tprintf (TEXT("Restore missing symbols\n"
		 "-----------------------\n")) ;
  
  _tprintf (TEXT("Opening %s... "), szOutputFile) ;

  hSymFile = SymFile_Load (szOutputFile) ;

  if( hSymFile == NULL ) {
    _tprintf (TEXT("Failed\n\n")) ;
    return 1 ;
  }

  _tprintf (TEXT("OK\n")) ;

  for( i=0 ; i<VERSION_COUNT ; i++ )
    {
      if( aVersions[i].bDisabled )
	{
	  HSYMKERN hSymKern ;

	  _tprintf (TEXT("%s... "), aVersions[i].szName) ;

	  hSymKern = SymFile_GetKernel (hSymFile, aVersions[i].szSymSignature) ;

	  if( hSymKern != NULL )
	    {
	      for( j=0 ; j<FUNCTION_COUNT ; j++ )
		aVersions[i].aFunctions[j] = (VOID*)SymFile_GetProcAddress(hSymFile, hSymKern, aFunctionNames[j]) ;
	      
	      aVersions[i].bDisabled = FALSE ;
	      _tprintf (TEXT("OK\n")) ;
	    }
	  else
	    {
	      _tprintf (TEXT("Not present in file\n")) ;
	    }
	}
    }

  SymFile_CloseFile (hSymFile) ;

  _tprintf (TEXT("\n")) ;

  return TRUE ;
}


BOOL WriteProgramFile () 
{
  TCHAR	szBackupFile[MAX_PATH] ;
  HSYMFILE hSymFile ;
  int i, j ;

  _tprintf (TEXT("Generate symbol file for Winpooch\n"
		 "---------------------------------\n")) ;

  _tprintf (TEXT("Backuping existing %s..."), szOutputFile) ;

  _tcscpy (szBackupFile, szOutputFile) ;
  _tcscat (szBackupFile, TEXT("~")) ;
  CopyFile (szOutputFile, szBackupFile, FALSE) ;

  _tprintf (TEXT("OK\n")) ;
  
  _tprintf (TEXT("Generating %s..."), szOutputFile) ;

  hSymFile = SymFile_New (FUNCTION_COUNT, aFunctionNames) ;
  
  for( i=0 ; i<VERSION_COUNT ; i++ )
    {
      HSYMKERN hSymKern ; 
 
      if( aVersions[i].bDisabled ) continue ;

      hSymKern = SymFile_AddKernel (hSymFile) ;

      SymFile_SetKernelName (hSymFile, hSymKern, aVersions[i].szName) ;
      SymFile_SetKernelSignature (hSymFile, hSymKern, aVersions[i].szSymSignature) ;

      for( j=0 ; j<FUNCTION_COUNT ; j++ )
	{	  
	  SymFile_SetProcAddress (hSymFile, hSymKern, aFunctionNames[j], 
				  (INT_PTR)aVersions[i].aFunctions[j]) ;

	  if( aVersions[i].aFunctions[j] == NULL )
	    {
	      if( strcmp(aFunctionNames[j],TEXT("NtCreateProcessEx")) && 
		  strcmp(aFunctionNames[j],TEXT("NtCreateUserProcess")) &&
		  strcmp(aFunctionNames[j],TEXT("PspTerminateProcess")) &&
		  strcmp(aFunctionNames[j],TEXT("ExfAcquirePushLockExclusive")) &&
		  strcmp(aFunctionNames[j],TEXT("ExfReleasePushLock")) )
		printf ("Warning: symbol %s not found for %s\n", aFunctionNames[j], aVersions[i].szName) ;
	    }
	}
    }

  if( ! SymFile_Save (hSymFile, szOutputFile) )
    {
      SymFile_CloseFile (hSymFile) ; 
      
      _tprintf (TEXT("Failed\n")) ;
    }

  SymFile_CloseFile (hSymFile) ; 
  _tprintf (TEXT("OK\n")) ;

  return TRUE ;
}

BOOL CheckTableIntegrity ()
{
  int i, j ;

  _tprintf (TEXT("Check table integrity\n"
		 "---------------------\n")) ;
  
  _tprintf (TEXT("Version name must be unique..... ")) ;  
  for( i=0 ; i<VERSION_COUNT ; i++ )
    {
      for( j=0 ; j<i ; j++ )
	{
	  if( i!=j && !_tcsicmp(aVersions[i].szName,aVersions[j].szName) )
	    {
	      _tprintf (TEXT("aVersions[%d].szName == aVersions[%d].szName\n"), i, j) ;
	      return FALSE ;
	    }
	}
    }
  _tprintf (TEXT("OK\n")) ; 

  _tprintf (TEXT("Signature must be unique........ ")) ;  
  for( i=0 ; i<VERSION_COUNT ; i++ )
    {
      for( j=0 ; j<i ; j++ )
	{
	  if( i!=j && !_tcsicmp(aVersions[i].szSymSignature,aVersions[j].szSymSignature) )
	    {
	      _tprintf (TEXT("aVersions[%d].szSymSignature == aVersions[%d].szSymSignature\n"), i, j) ;
	      return FALSE ;
	    }
	}
    }
  _tprintf (TEXT("OK\n")) ;

  _tprintf (TEXT("\n")) ;

  return TRUE ;
}


int main (int argc, char * argv[])
{	
  TCHAR szDirectory[MAX_PATH] ;

  if( argc > 1 ) szPrefix = argv[1] ;
  
  GetCurrentDirectory (MAX_PATH, szDirectory) ;
  _stprintf (szOutputFile, TEXT("\\??\\%s\\Symbols.wps"), szDirectory) ;

  // disable bufferingon STDOUT
  setvbuf (stdout, NULL, _IONBF, 0) ;

  BOOL bSuccess = 
    CheckTableIntegrity ()
    &&
    DownloadMissingFiles () 
    &&
    ReadSymbolFiles () 
    &&
    RestoreMissingSymbols ()
    &&
    WriteProgramFile () ;
  
  return bSuccess ? 0 : 1 ;
}
